package com.aspirecn.core.datacache.useragent;

import java.io.File;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.log4j.Logger;

import com.aspire.core.match.ua.object.Device;
import com.aspirecn.core.commons.Configuration;
import com.aspirecn.core.commons.ObjectUtils;
import com.aspirecn.core.datacache.BaseLocalCache;
import com.csvreader.CsvReader;

/**
 * device数据缓存
 * 
 * @author wangxinning
 * 
 */
public class DeviceCache extends BaseLocalCache {

	public final static Logger logger = Logger.getLogger(DeviceCache.class);

	private List<Integer> deviceIDList = new ArrayList<Integer>();
	private Map<Integer,Device> deviceMap = new HashMap<Integer,Device>();

	private static DeviceCache instance = new DeviceCache();
	private MMDeviceIDCache mmDeviceIDCache = MMDeviceIDCache.getInstance();

	private DeviceCache() {

		this.dataFile = new File(Configuration.getInstance()
				.getDownloadFilePath()
				+ File.separator
				+ "uaV3"
				+ File.separator + "device.csv");
		load();
	}

	public static DeviceCache getInstance() {
		return instance;
	}

	public void load() {

		if (!loading.getAndSet(true)
				&& Configuration.getInstance().switchUACache()
				&& this.dataFile.exists()) {

			this.clear();
			
			long start = System.currentTimeMillis();

			try {

				CsvReader reader = new CsvReader(this.dataFile.toString(), ',',
						Charset.forName("gbk"));

				while (reader.readRecord()) {

					if (reader.getCurrentRecord() == 0)// 设置列名
					{
						reader.setHeaders(reader.getValues());
					} else {
						Device device = new Device();
						
						device.setBrand_id(NumberUtils.toInt(reader
								.get("BRAND_ID")));
						device.setDevice_desc(StringUtils.remove(reader.get("DEVICE_DESC"), "(null)"));
						device.setDevice_first_alpha(StringUtils.remove(reader.get("DEVICE_FIRST_ALPHA"), "(null)"));
						device.setDevice_id(NumberUtils.toInt(reader
								.get("DEVICE_ID")));
						device.setDevice_name(StringUtils.remove(reader.get("DEVICE_NAME"), "(null)"));
						//device.setDevice_os_ua(StringUtils.remove(reader.get("KEYWORD2"), "(null)"));
						//device.setDevice_ua(StringUtils.remove(reader.get("KEYWORD2"), "(null)"));
						device.setEnglish_device_desc(StringUtils.remove(reader.get("ENGLISH_DEVICE_DESC"), "(null)"));
						device.setEnglish_device_name(StringUtils.remove(reader.get("ENGLISH_DEVICE_NAME"), "(null)"));
						device.setOs_detail(StringUtils.remove(reader.get("OS_DETAIL"), "(null)"));
						device.setOs_id(NumberUtils.toInt(reader
								.get("OS_ID")));
						device.setPreviewPicwww(StringUtils.remove(reader.get("PREVIEW_PIC_WWW"), "(null)"));
						device.setScreensize(StringUtils.remove(reader.get("SCREENSIZE"), "(null)"));
						device.setSeries_id(NumberUtils.toInt(reader
								.get("SERIES_ID")));
						device.setTouchScreen(StringUtils.equals(StringUtils.remove(reader.get("IS_TOUCH_SCREEN"), "(null)"),"是"));
						
						if( Configuration.getInstance().isMM() )
						{
							//MM系统，如果不在范围，不添加入缓存
							if( !mmDeviceIDCache.isExist(device.getDevice_id()) )
							{
								continue;
							}
						}						
						
						deviceIDList.add(device.getDevice_id());
						deviceMap.put(device.getDevice_id(), device);
					}
				}

				reader.close();

			} catch (Exception e) {
				logger.error("Device信息加载异常", e);
			}

			loading.set(false);
			long end = System.currentTimeMillis();
			updateFileDownloadTime();
			logger.info("Device信息加载完成，time=" + (end - start) + "ms,size="
					+ deviceIDList.size());

		} else {
			loading.set(false);
			logger.info("配置关闭，Device信息未加载");
		}

		loading.set(false);
	}

	@Override
	public void clear() {

		deviceIDList.clear();
		deviceMap.clear();
	}

	@Override
	public void reload() {

		if (this.fileIsChange()) {
			this.load();
		} else {
			logger.info("没变化，Device信息未加载");
		}
	}

	public List<Device> getAllDevice() {
		
		List<Device> retList = new ArrayList<Device>();
		for( Integer deviceID:deviceIDList )
		{
			Device device = this.deviceMap.get(deviceID);
			if( device != null )
			{
				retList.add(device);
			}			
		}
		return retList;
	}
	
	//精确匹配，根据某一个字段搜索，匹配的第一个返回
	public Device getDeviceByColume( String content, String[] columeNames ) {
		
		for( Integer deviceID:deviceIDList )
		{
			Device device = this.deviceMap.get(deviceID);
			if( device != null )
			{
				for( String columeName:columeNames )
				{
					String tempContent = null;
					try {
						tempContent = BeanUtils.getSimpleProperty(device, columeName);
					} catch (Exception e) {
						e.printStackTrace();
					}
					
					if( StringUtils.equals(content, tempContent) )
					{
						return this.getDevice(deviceID);
					}
				}
			}			
		}
		
		return null;
	}
	
	public Device getDevice( int deviceid ) {
		Device device = this.deviceMap.get(deviceid);
		if( device != null )
		{
			try {
				return (Device)BeanUtils.cloneBean(device);
			} catch (Exception e) {
				logger.error("克隆device错误", e);
			}
		}
		return device;
	}
	
	
	public List<Device> searchDevice( String keyword )
	{
		List<Device> list = new ArrayList<Device>();
		
		Iterator<Integer> keyIte = deviceMap.keySet().iterator();
		
		Map<Integer,Object> filter = new HashMap<Integer,Object>();//去重
		while( keyIte.hasNext() )
		{
			Integer keyInt = keyIte.next();
			Device tempDevice = deviceMap.get(keyInt);
			
			if (tempDevice != null && !filter.containsKey(keyInt) &&
					(StringUtils.containsIgnoreCase(tempDevice.getDevice_name(),
					keyword) || StringUtils.containsIgnoreCase(
							tempDevice.getDevice_desc(), keyword))) {
				list.add(tempDevice);
				filter.put(keyInt, null);
			}			
		}

		return list;
	}
	
	
	//跟上面方法比，仅增加了品牌判断
	public List<Device> searchDevice( int brandid, String keyword )
	{
		List<Device> list = new ArrayList<Device>();
		
		Iterator<Integer> keyIte = deviceMap.keySet().iterator();
		
		Map<Integer,Object> filter = new HashMap<Integer,Object>();//去重
		while( keyIte.hasNext() )
		{
			Integer keyInt = keyIte.next();
			Device tempDevice = deviceMap.get(keyInt);
			
			if (tempDevice != null && !filter.containsKey(keyInt) &&
					(StringUtils.containsIgnoreCase(tempDevice.getDevice_name(),
					keyword) || StringUtils.containsIgnoreCase(
							tempDevice.getDevice_desc(), keyword))
							&&
							tempDevice.getBrand_id() == brandid) {
				list.add(tempDevice);
				filter.put(keyInt, null);
			}			
		}

		return list;
	}
	
	
	public List<Device> getBrandDeviceList( int brandid )
	{
		List<Device> list = new ArrayList<Device>();		
		Iterator<Integer> keyIte = deviceMap.keySet().iterator();
		
		Map<Integer,Object> filter = new HashMap<Integer,Object>();//去重
		while( keyIte.hasNext() )
		{
			Integer keyInt = keyIte.next();
			Device tempDevice = deviceMap.get(keyInt);
			
			if (tempDevice != null && !filter.containsKey(keyInt) &&
					( tempDevice.getBrand_id() == brandid )) {
				list.add(tempDevice);
				filter.put(keyInt, null);
			}			
		}

		return list;
	}
	
	
	public List<Device> getBrandAlphaDeviceList(int brandID, String firstAlpha)
	{
		List<Device> list = new ArrayList<Device>();		
		Iterator<Integer> keyIte = deviceMap.keySet().iterator();
		
		Map<Integer,Object> filter = new HashMap<Integer,Object>();//去重
		while( keyIte.hasNext() )
		{
			Integer keyInt = keyIte.next();
			Device tempDevice = deviceMap.get(keyInt);
			
			if (tempDevice != null
					&& !filter.containsKey(keyInt)
					&& (tempDevice.getBrand_id() == brandID)
					&& StringUtils.equals(tempDevice.getDevice_first_alpha(),
							firstAlpha)) {
				list.add(tempDevice);
				filter.put(keyInt, null);
			}		
		}

		return list;
	}
	
	
	
	public List<String> getBrandAlphaList(int brandID)
	{
		List<String> list = new ArrayList<String>();		
		Iterator<Integer> keyIte = deviceMap.keySet().iterator();
		
		Map<String,Object> filter = new HashMap<String,Object>();//去重
		while( keyIte.hasNext() )
		{
			Integer keyInt = keyIte.next();
			Device tempDevice = deviceMap.get(keyInt);
			
			if (tempDevice != null
					&& !filter.containsKey(tempDevice.getDevice_first_alpha())
					&& (tempDevice.getBrand_id() == brandID)) {
				list.add(tempDevice.getDevice_first_alpha());
				filter.put(tempDevice.getDevice_first_alpha(), null);
			}
		}

		//排序
		if( !ObjectUtils.isEmptyList(list) )
		{
			Collections.sort(list);
		}
		
		return list;
	}
	

	public static void main(String[] args) {
		long start = System.currentTimeMillis();
		DeviceCache geoCache = DeviceCache.getInstance();
//		System.out.println(geoCache.getDeviceByColume("Hisense HS-T30", new String[]{"device_name"}));
//		long end = System.currentTimeMillis();

		//487
		List<Device> sList = geoCache.getBrandAlphaDeviceList(487,"D");
		//Collections.sort(sList);
		System.out.println( sList );
		
		//System.out.println(end - start);

	}
}